package cn.q3c.stock.service;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;

import cn.keyvalue.ccf.common.util.ObjectUtils;
import cn.q3c.stock.commons.Configuration;
import cn.q3c.stock.object.StockDayLine;
import cn.q3c.stock.object.StockInfo;
import cn.q3c.stock.object.StockTradeLog;

public class StockServiceImpl implements StockService {

	private static final Logger logger = Logger
			.getLogger(StockServiceImpl.class);

	// 处理一直股票一天的交易数据/
	public boolean processTradeOneDay(List<StockTradeLog> stockTradeLogList) {

		try {
			if (!ObjectUtils.isEmptyList(stockTradeLogList)) {
				// 1.交易日期
				Date tradeDate = getTradeDate(stockTradeLogList.get(0));

				// 2.转换StockID
				int stockID = stockTradeLogList.get(0).getStockID();
//						stockCodeToSystemStockID(stockTradeLogList.get(0)
//						.getDirection(), stockTradeLogList.get(0).);

				if (stockID > 0)// 合法性
				{
					// 3.查询当天日线，存在就不处理了
					StockDayLine stockDayLine = getStockDayLine(stockID,
							tradeDate);
					if (stockDayLine == null) {
						// 4.入库日志
						addTradeLogList(stockTradeLogList);

						// 5.计算日线
						stockDayLine = calStockDayLine(stockTradeLogList);
						//logger.debug( stockDayLine );
						
						addStockDayLine(stockDayLine);
					}
					else
					{
						logger.debug("  存在日线数据，跳过 stockID=" + stockID);
					}
				}
			}

			return true;
		} catch (Exception e) {
			logger.error("交易数据入库异常", e);
			return false;
		}
	}

	// 股票代码转换为系统自定义的股票ID
	public int stockCodeToSystemStockID(int sctype, String stockCode) throws Exception
	{
		StockInfo stockInfo = getStockInfo( sctype, stockCode );
		
		if( stockInfo != null )
		{
			return stockInfo.getId();
		}
		
		return -1;
	}

	// 获取交易日期
	private Date getTradeDate(StockTradeLog stockTradeLog) {
		return stockTradeLog.getTradingDate();
	}

	private StockInfo getStockInfo(int sctype, String stockCode) throws ConfigurationException, ClassNotFoundException, SQLException {

		QueryRunner qr = new QueryRunner();
		String sql = "select * from Stocks where code=? and exchange=?";
		Object[] params = new Object[]{stockCode, sctype==1?"sh":"sz"};
		
		Connection conn = getConnection();
		
		StockInfo result = null;
		result = (StockInfo) qr.query(conn, sql,
				new BeanHandler<StockInfo>(StockInfo.class), params);

		return result;
	}	
	
	private StockDayLine getStockDayLine(int stockID, Date date) throws ConfigurationException, ClassNotFoundException, SQLException {
		//String dateStr = DateFormatUtils.format(date, "yyyy-MM-dd");

		QueryRunner qr = new QueryRunner();
		String sql = "select * from DailyBars where stockID=? and tradingDate=date_format(?,'%Y-%m-%d')";
		Object[] params = new Object[]{stockID, date};
		
		Connection conn = getConnection();
		
		StockDayLine result = null;
		result = (StockDayLine) qr.query(conn, sql,
				new BeanHandler<StockDayLine>(StockDayLine.class), params);

		return result;
	}

	// 写入交易日志
	private void addTradeLogList(List<StockTradeLog> stockTradeLogList)
			throws ConfigurationException, ClassNotFoundException, SQLException {

		QueryRunner qr = new QueryRunner();
		String sql = "insert into TradeLog(stockID,tradingDate,price,volume,value,direction,tradingTime)" +
				" values(?,?,?,?,?,?,?)";

		Connection conn = getConnection();
		//Object[][] batchobjs = null;
		for (StockTradeLog log : stockTradeLogList) {

			Object[] objs = new Object[] {
					
					log.getStockID(),
					log.getTradingDate(),
					log.getPrice(),
					log.getVolume(),
					log.getValue(),
					log.getDirection(),
					log.getTradingTime()
					
			};
			//batchobjs = (Object[][]) ArrayUtils.add(batchobjs, objs);
			
			
			qr.update(conn, sql, objs);// 批量提交
		}
	}

	// 计算日线
	private StockDayLine calStockDayLine(List<StockTradeLog> stockTradeLogList) {
		
		//1.找到开盘价和收盘价记录
		StockTradeLog startLog = null;
		StockTradeLog endLog = null;
		float[] prices = null;
		Float sumPrices = NumberUtils.toFloat("0");
		Integer[] volumes = null;
		Integer sumVolumes = 0;
		Integer[] values = null;
		Integer sumValues = 0;
		
		for( StockTradeLog log:stockTradeLogList )
		{
			prices = ArrayUtils.add(prices, log.getPrice());
			volumes = ArrayUtils.add(volumes, log.getVolume());
			values = ArrayUtils.add(values, log.getValue());
			
			sumPrices += log.getPrice();
			sumVolumes += log.getVolume();
			sumValues += log.getValue();
			
			if( startLog == null || log.getTradingTime().getTime() < startLog.getTradingTime().getTime() )
			{
				startLog = log;
			}
			
			if( endLog == null || log.getTradingTime().getTime() > endLog.getTradingTime().getTime() )
			{
				endLog = log;
			}
		}
		
		StockDayLine retStockDayLine = new StockDayLine();
		retStockDayLine.setAvgPx(sumPrices/prices.length);
		retStockDayLine.setClosePx(endLog.getPrice());
		retStockDayLine.setOpenPx(startLog.getPrice());
		retStockDayLine.setHighPx(NumberUtils.max(prices));
		retStockDayLine.setLowPx(NumberUtils.min(prices));
		retStockDayLine.setStockID(stockTradeLogList.get(0).getStockID());
		retStockDayLine.setValue(sumValues);
		retStockDayLine.setVolume(sumVolumes);
		retStockDayLine.setTradingDate(stockTradeLogList.get(0).getTradingDate());		
		
		return retStockDayLine;
	}

	// 添加股票日线数据
	private void addStockDayLine(StockDayLine stockDayLine) throws ConfigurationException, ClassNotFoundException, SQLException {
		
		QueryRunner qr = new QueryRunner();
		String sql = "insert into DailyBars(stockID,tradingDate,openPx,closePx,highPx,lowPx,avgPx,volume,value)" +
				" values(?,?,?,?,?,?,?,?,?)";

		Object[] objs = new Object[]{
				stockDayLine.getStockID(),stockDayLine.getTradingDate(),
				stockDayLine.getOpenPx(),stockDayLine.getClosePx(),stockDayLine.getHighPx(),
				stockDayLine.getLowPx(),stockDayLine.getAvgPx(),stockDayLine.getVolume(),
				stockDayLine.getValue()
		};

		Connection conn = getConnection();
		qr.update(conn, sql, objs);// 批量提交
		
	}

	private Connection m_conn = null;

	public Connection getConnection() throws ClassNotFoundException,
			ConfigurationException, SQLException {
		if (m_conn == null) {
			Class.forName(Configuration.getInstance().getConfig().getString("db.driver"));
			Connection conn = DriverManager.getConnection(
					Configuration.getInstance().getConfig().getString("db.connUrl"),
					Configuration.getInstance().getConfig().getString("db.username"),
					Configuration.getInstance().getConfig().getString("db.password"));
			m_conn = conn;
		}

		return m_conn;
	}
	
	
	
	
	
	
	public static void main( String[] args ) throws ConfigurationException, ClassNotFoundException, SQLException
	{
		StockServiceImpl stockService = new StockServiceImpl();
//		StockDayLine stockDayLine = new StockDayLine();
//		stockDayLine.setAvgPx(0.0);
//		stockDayLine.setClosePx(0.0);
//		stockDayLine.setHighPx(0.0);
//		stockDayLine.setLowPx(0.0);
//		stockDayLine.setOpenPx(0.0);
//		stockDayLine.setStockID(1);
//		stockDayLine.setTradingDate(new Date());
//		stockDayLine.setValue(0.0);
//		stockDayLine.setVolume(0);
		//stockService.addStockDayLine(stockDayLine);		
		System.out.println(stockService.getStockInfo(1, "600000"));
		
		
		StockTradeLog log = new StockTradeLog();
		log.setDirection(1);
		log.setPrice((float)0.0);
		log.setStockID(1);
		log.setTradingDate(new Date());
		log.setTradingTime(new Date());
		log.setValue(0);
		log.setVolume(0);
		
		List<StockTradeLog> ll = new ArrayList<StockTradeLog>();
		ll.add(log);
		//stockService.addTradeLogList(ll);
		
		
	}
}
